/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.intel.factorytest.activity;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

public class PointerLocationViewRect1 extends View {
    private static final String TAG = "PointerLocationViewRect1";
    private static int RECTLEN = 50;
    private int remainderH = 0;
    private int remainderV = 0;
    private int remainderCount = 0;
    private int rectCountH = 0;
    private int rectCountV = 0;
    private int rectTotal = 0;
    
    private boolean isSendFinishMsg = false;
    
    private Context ctx;
    
    // screen width
    private int widthScr = 0;
    // screen height
    private int heightScr = 0;
    int midCoordsX = 0;
    int midCoordsY = 0;
    
    private Rect tmpRect = new Rect(0, 0, 0, 0);
    
    private PointerLocation activity;
    private int orientation = Configuration.ORIENTATION_PORTRAIT;
    
    
    private final Paint mRedPaint;
    private final Paint mGreenPaint;
    
    public PointerLocationViewRect1(Context ctx) {
        this(ctx, null);  
    }
    
    public PointerLocationViewRect1(Context context, AttributeSet attrs){  
        this(context, attrs, 0);  
    }  
    
    public PointerLocationViewRect1(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        this.ctx = context;
        activity = (PointerLocation) this.ctx;
        
        // 获取屏幕高度和宽度
        widthScr = activity.widthScreen;
        heightScr = activity.heightScreen;
        
        // 计算矩形边长
        initRectLen();
        
        // 计算中间位置
        midCoordsX = widthScr / 2 - widthScr / 2 % RECTLEN;
        midCoordsY = heightScr / 2 - heightScr / 2 % RECTLEN;

        Log.d(TAG,"rect1 widthScr = " + widthScr + ", heightScr=" + heightScr);

        // 计算水平方向与垂直方向上的余数
        remainderH = widthScr % RECTLEN;
        remainderV = heightScr % RECTLEN;
        if (remainderH == 0 && remainderV == 0) {
            remainderCount = 0;
        } else if (remainderH == 0 && remainderV != 0 || remainderH != 0 && remainderV == 0) {
            remainderCount = 1;
        } else {
            remainderCount = 2;
        }

        // 计算水平方向与垂直方向上矩形的个数
        rectCountH = widthScr / RECTLEN;
        rectCountV = heightScr / RECTLEN;

        Log.d(TAG, "rect1 rectCountH=" + rectCountH + ", rectCountV=" + rectCountV);

        // 计算矩形总数
        rectTotal = (rectCountH + rectCountV) * 3 - 8/* - (remainderCount * 3)*/;
        Log.d(TAG, " rect1 rectTotal = " + rectTotal);

        orientation = activity.getResources().getConfiguration().orientation;

        setFocusable(true);

        mRedPaint = new Paint();
        mRedPaint.setAntiAlias(true);
        mRedPaint.setARGB(255, 255, 80, 80);
        mRedPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mRedPaint.setStrokeWidth(2);

        mGreenPaint = new Paint();
        mGreenPaint.setAntiAlias(false);
        mGreenPaint.setARGB(255, 20, 255, 20);
        mGreenPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mGreenPaint.setStrokeWidth(2);

    }     
    
    @Override
    protected void onDraw(Canvas canvas) {
        synchronized (rectList) {
            initDrawn(canvas);
            
            for (Rect rect : rectList) {
                canvas.drawRect(rect, mGreenPaint);
            }
        }

    }
    
    private void initDrawn(Canvas canvas) {
        // draw left on vertical
        updateTmpRect(0, 0, RECTLEN, heightScr);
        canvas.drawRect(tmpRect, mRedPaint);
        // draw middle on vertical
        updateTmpRect(midCoordsX, 0, midCoordsX + RECTLEN, heightScr);
        canvas.drawRect(tmpRect, mRedPaint);
        // draw right on vertical
        updateTmpRect(widthScr - RECTLEN, 0, widthScr, heightScr);
        canvas.drawRect(tmpRect, mRedPaint);
        // draw top on horizontal
        updateTmpRect(0, 0, widthScr, RECTLEN);
        canvas.drawRect(tmpRect, mRedPaint);
        // draw middle on horizontal
        updateTmpRect(0, midCoordsY, widthScr, midCoordsY + RECTLEN);
        canvas.drawRect(tmpRect, mRedPaint);
        // draw bottom on horizontal
        updateTmpRect(0, heightScr - RECTLEN, widthScr, heightScr);
        canvas.drawRect(tmpRect, mRedPaint);
    }
    
    private List<String> greenRectList = new ArrayList<String>(); 
    
    private boolean isDrawned(int NX, int NY) {
        String value = NX + "," + NY;
        return greenRectList.contains(value);
    }
    
    private Rect updateTempRect(float coordsX, float coordsY) {
        
        boolean isUpdated = false;
        int NX = (int) coordsX / RECTLEN;
        int NY = (int) coordsY / RECTLEN;
        
        if (!isDrawned(NX, NY)) {
            greenRectList.add(NX + "," + NY);
        } else {
            return tmpRect;
        }
        
        // 对右边界和下边界的处理，因为如果有余数的话，会在这两条边上显示出来
        if (!isUpdated) {
            if (coordsX > widthScr - (RECTLEN + remainderH)) {
                int left = widthScr - (RECTLEN + remainderH);
                int top = 0;
                int right = widthScr;
                int bottom = 0;
                if (coordsY < RECTLEN) {
                    top = 0;
                    bottom = RECTLEN;
                    updateTmpRect(left, top, right, bottom);
                } else if (coordsY > heightScr - (RECTLEN + remainderV)) {
                    
                    top = heightScr - RECTLEN;
                    bottom = heightScr;
                    updateTmpRect(left, top, right, bottom);
                    if (!isExist(tmpRect)) {
                        rectList.add(new Rect(tmpRect));
                    }
                    
                    left = widthScr - RECTLEN;
                    top = heightScr - (RECTLEN + remainderV);
                    updateTmpRect(left, top, right, bottom);
                    if (!isExist(tmpRect)) {
                        rectList.add(new Rect(tmpRect));
                    }
                    return tmpRect;
                } else if (coordsY > midCoordsY && coordsY < midCoordsY + RECTLEN) {
                    top = midCoordsY;
                    bottom = midCoordsY + RECTLEN;
                    updateTmpRect(left, top, right, bottom);
                } else {
                    left = widthScr - RECTLEN;
                    top = NY * RECTLEN;
                    bottom = (NY + 1) * RECTLEN;
                    updateTmpRect(left, top, right, bottom);
                }
                isUpdated = true;
            }
        }
        
        if (!isUpdated) {
            if (coordsY > heightScr - (RECTLEN + remainderV)) {
                int left = 0;
                int top = heightScr - (RECTLEN + remainderV);
                int right = 0;
                int bottom = heightScr;
                if (coordsX < RECTLEN) {
                    right = RECTLEN;
                    updateTmpRect(left, top, right, bottom);
                } else if (coordsX > widthScr - RECTLEN) {
                    left = widthScr - RECTLEN;
                    right = widthScr;
                    updateTmpRect(left, top, right, bottom);
                } else if (coordsX > midCoordsX && coordsX < midCoordsX + RECTLEN) {
                    left = midCoordsX;
                    right = midCoordsX + RECTLEN;
                    updateTmpRect(left, top, right, bottom);
                } else {
                    left = NX * RECTLEN;
                    top = heightScr - RECTLEN;
                    right = (NX + 1) * RECTLEN;
                    bottom = heightScr;
                    updateTmpRect(left, top, right, bottom);
                }
                isUpdated = true;
            }
        }
        
        if (!isUpdated) {
            updateTmpRect(NX * RECTLEN, NY * RECTLEN, (NX + 1) * RECTLEN, (NY + 1) * RECTLEN);
        }
        
        // 如果该矩形与其它任何一个矩形有交叉，则丢弃
        boolean isIntersect = false;
        for (Rect rect : rectList) {
            if (Rect.intersects(tmpRect, rect)) {
                isIntersect = true;
            }
        }
//        if (tmpRect.right == widthScr && (tmpRect.top == heightScr - (RECTLEN + remainderV) || tmpRect.left == widthScr - (RECTLEN + remainderH))) {
//            // do nothing
//        } else {
//        }
        
        if (!isIntersect && !isExist(tmpRect)) {
            rectList.add(new Rect(tmpRect));
        }
        
        return tmpRect;
    }
    
    private void updateTmpRect(int left, int top, int right, int bottom) {
        tmpRect.left = left;
        tmpRect.top = top;
        tmpRect.right = right;
        tmpRect.bottom = bottom;
    }
    
    private boolean isExist(Rect target) {
        if (target == null) {
            return false;
        }
        for (Rect rect : rectList) {
            if (rect.left == target.left && rect.top == target.top && rect.right == target.right && rect.bottom == target.bottom) {
                return true;
            }
        }
        return false;
    }
    
    private List<Rect> rectList = new ArrayList<Rect>();
    
    public void addTouchEvent1(MotionEvent event) {
        
        int action = event.getAction();
        if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) {
            
            int coordsX = (int) event.getX();
            int coordsY = (int) event.getY();
            
            if (!isValidArea(coordsX, coordsY)) {
                return;
            }
            
            
            int NX = (int) coordsX / RECTLEN;
            int NY = (int) coordsY / RECTLEN;
            
            if (isDrawned(NX, NY)) {
                return;
            }
            
            updateTempRect(coordsX, coordsY);
            
            if (tmpRect.right > widthScr || tmpRect.bottom > heightScr) {
                return;
            }
            
            if (!isSendFinishMsg) {
                if (rectList.size() == rectTotal) {
                    activity.setIs_pass(true);
                    activity.finish();
                    isSendFinishMsg = true;
                }
            }
            
            postInvalidate();
        }
        
        
    }
    
    private boolean isValidArea(float coordX, float coordY) {
        boolean shown = true;
        
        if (coordX >= RECTLEN && coordX <= midCoordsX && coordY >= RECTLEN && coordY <= midCoordsY
                || coordX >= midCoordsX + RECTLEN && coordX <= widthScr - RECTLEN && coordY >= RECTLEN && coordY <= midCoordsY
                || coordX >= RECTLEN && coordX <= midCoordsX && coordY >= midCoordsY + RECTLEN && coordY <= heightScr - RECTLEN
                || coordX >= midCoordsX + RECTLEN && coordX <= widthScr - RECTLEN && coordY >= midCoordsY + RECTLEN && coordY <= heightScr - RECTLEN
                || coordX >= widthScr
                || coordY >= heightScr - 3) {
            shown = false;
        }
        
        
        return shown;
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        int action = event.getAction();
        if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_MOVE) {
            
            int coordsX = (int) event.getX();
            int coordsY = (int) event.getY();
            
            if (!isValidArea(coordsX, coordsY)) {
                return true;
            }
            
            
            int NX = (int) coordsX / RECTLEN;
            int NY = (int) coordsY / RECTLEN;
            
            if (isDrawned(NX, NY)) {
                return true;
            }
            
            updateTempRect(coordsX, coordsY);
            
            if (tmpRect.right > widthScr || tmpRect.bottom > heightScr) {
                return true;
            }
            
            if (!isSendFinishMsg) {
                if (rectList.size() == rectTotal) {
                    activity.setIs_pass(true);
                    activity.finish();
                    isSendFinishMsg = true;
                }
            }
            
            postInvalidate();
//            canvas.drawRect(tmpRect, mGreenPaint);
        }else if (action == MotionEvent.ACTION_UP){
            postInvalidate();
        }
        return true;
    }
    
    private void initRectLen() {
        int orientation = activity.getResources().getConfiguration().orientation;
        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
            if (heightScr  <= 1280) { // 7寸
                RECTLEN = 50;
            } else if (heightScr <= 2048) {// 8寸
                RECTLEN = 80;
            }
        } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
            if (widthScr <= 1280) {
                RECTLEN = 50;
            } else if (widthScr <= 2048) {
                RECTLEN = 80;
            }
        }
    }
    
}
